package com.jcl.mybatistypehandler.handler;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.jcl.mybatistypehandler.model.MyEncrypt;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(MyEncrypt.class)
public class MyEncryptTypeHandler extends BaseTypeHandler<MyEncrypt> {

    private static final byte[] KEYS = "12345678abcdefgh".getBytes(StandardCharsets.UTF_8);

    /**
     * 设置参数,默认从前端传来是源手机号，加密处理后，又重新塞回
     * preparedStatement: 预执行句柄
     */
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, MyEncrypt myEncrypt, JdbcType jdbcType) throws SQLException {
        if (myEncrypt == null || myEncrypt.getRealPhone() == null) {
            preparedStatement.setString(i, null);
            return;
        }
        String s = Optional.ofNullable(jdbcType).map(Enum::name).orElse("未获取！");
        System.out.println("s = " + s);
        String phone = myEncrypt.getRealPhone();
        AES aes = SecureUtil.aes(KEYS);
        String encrypt = aes.encryptHex(phone);
        preparedStatement.setString(i, encrypt);
    }

    @Override
    public MyEncrypt getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return decrypt(resultSet.getString(s));
    }

    @Override
    public MyEncrypt getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return decrypt(resultSet.getString(i));
    }

    @Override
    public MyEncrypt getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return decrypt(callableStatement.getString(i));
    }

    /**
     * 解密
     *
     * @param value 手机号
     * @return 返回解密对象
     */
    public MyEncrypt decrypt(String value) {
        if (null == value) {
            return null;
        }
        return new MyEncrypt(SecureUtil.aes(KEYS).decryptStr(value));
    }
}
